package com.example.demo.controller;

import com.example.demo.domain.result.ScheduleResult;
import com.example.demo.domain.result.helper.DeletedScheduleResult;
import com.example.demo.exception.PasswordErrorException;
import com.example.demo.exception.ScheduleNotExistException;
import com.example.demo.result.ApiResult;
import com.example.demo.result.ResultCode;
import com.example.demo.service.*;
import com.example.demo.utils.ParseUtil;
import com.google.gson.Gson;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.IOException;

/**
 * @author lizijian
 */
@RestController
@RequestMapping("/School/schedule")
@Slf4j
@Validated
public class ScheduleController {

  private static final Gson GSON = new Gson();

  @Autowired
  private ScheduleService scheduleService;


  private static final String HBUT_START_TIME = "2021-09-06";

  private static final String HBUT_ETC_START_TIME = "2021-09-06";

  @ApiOperation(value = "查询某一个班级的课表")
  @ApiImplicitParams({
      @ApiImplicitParam(name = "classId", value = "班级编号", required = true, paramType = "query"),
      @ApiImplicitParam(name = "className", value = "班级名", required = true, paramType = "query"),
      @ApiImplicitParam(name = "campusId", value = "学院编号", required = true, paramType = "query"),
      @ApiImplicitParam(name = "userId", value = "用户编号", required = true, paramType = "query"),
      @ApiImplicitParam(name = "username", value = "教务账号", required = true, paramType = "query"),
      @ApiImplicitParam(name = "password",value = "教务密码",required = true,paramType = "query")})
  @GetMapping("/class")
  public ApiResult<ScheduleResult> classSchedule(
      @NotNull(message = "classId不能为null") Integer classId,
      @NotBlank(message = "className不能为空") String className,
      @NotNull(message = "campusId不能为空") Integer campusId,
      @NotNull(message = "userId不能为空") Integer userId, String username,String password,@RequestParam(required = false,defaultValue = "true") boolean isMyClass)
      throws PasswordErrorException, IOException, ScheduleNotExistException {
    ScheduleResult result = null;
    //查询工程学院课表
    if (2 == campusId) {
      result = scheduleService.getHbutEtcSchedule(classId);
      result.setStartTime(HBUT_ETC_START_TIME);
    } else {
      result = scheduleService.queryHbutScheduleByClassName(className);
      result.setStartTime(HBUT_START_TIME);
    }
    return ApiResult.success(scheduleService.mixSchedule(userId, result, username,password,campusId,isMyClass));
  }

  @ApiOperation(value = "使用教务系统账号密码查询自己的课表")
  @ApiImplicitParams({
      @ApiImplicitParam(name = "username", value = "教务系统账号", required = true, paramType = "query"),
      @ApiImplicitParam(name = "password", value = "教务系统密码", required = true, paramType = "query"),
      @ApiImplicitParam(name = "classId", value = "班级编号", required = true, paramType = "query"),
      @ApiImplicitParam(name = "campusId", value = "学院编号", required = true, paramType = "query"),
      @ApiImplicitParam(name = "className", value = "班级名称", required = true, paramType = "query"),
      @ApiImplicitParam(name = "userId", value = "用户编号", required = true, paramType = "query")})
  @RequestMapping("/personal")
  public ApiResult<ScheduleResult> schedule(@NotNull(message = "username不能为null") String username,
      @NotNull(message = "password不能为null") String password,
      @NotNull(message = "classId不能为空") Integer classId,
      @NotNull(message = "campusId不能为空") Integer campusId,
      @NotBlank(message = "className不能为空") String className, @NotNull Integer userId)
      throws IOException, PasswordErrorException {
    ScheduleResult result = null;
    //工程学院课表
    if (2 == campusId) {
      result = ParseUtil.getHbutEtcSchedule(username, password, className);
      scheduleService.addHbutEtcSchedule(classId, className, GSON.toJson(result.getSchedule()));
      result.setStartTime(HBUT_ETC_START_TIME);
    } else {
      result = ParseUtil.getHbutPersonalSchedule(username, password);
      result.setStartTime(HBUT_START_TIME);
    }
    return ApiResult.success(scheduleService.mixSchedule(userId, result, username,password,campusId,true));
  }

  @ApiOperation(value = "添加自定义课程")
  @PostMapping("/own/add")
  public ApiResult<?> addOwnSchedule(@NotBlank String weeks, @NotNull Integer day,
      @NotNull Integer lesson,
      String address, @NotBlank String name, @NotNull Integer userId) {
    GSON.fromJson(weeks, Integer[].class);
    if (scheduleService.existSameNameSchedule(userId, name)) {
      return ApiResult.fail(ResultCode.INVALID_PARAM, "exists the same name course", "存在同名自定义课程",
          null);
    }
    scheduleService.addOwnSchedule(userId, name, address, weeks, day, lesson);
    return ApiResult.success();
  }

  @ApiOperation("修改自定义课程时间")
  @ApiImplicitParams({
      @ApiImplicitParam(name = "scheduleId", value = "自定义课程id", required = true, paramType = "query"),
      @ApiImplicitParam(name = "scheduleTimeId", value = "自定义课程时间id,如果为空则新增时间，不为空则修改时间", required = false, paramType = "query")})
  @PostMapping("/own/time/modify")
  public ApiResult<?> modifyOwnScheduleTime(@NotNull Integer scheduleId, Integer scheduleTimeId,
      @NotBlank String weeks, @NotNull Integer day, @NotNull Integer lesson,
      String address) {
    GSON.fromJson(weeks, Integer[].class);
    try {
      if (scheduleTimeId == null) {
        scheduleService.addOwnScheduleTime(scheduleId, address, weeks, day, lesson);
      } else {
        scheduleService.updateOwnScheduleTime(scheduleTimeId, address, weeks, day, lesson);
      }
    } catch (DuplicateKeyException e) {
      log.error(e.getMessage());
      return ApiResult.fail(ResultCode.INVALID_PARAM, "customize course existed now",
          "当前时间段已存在自定义课程", null);
    }
    return ApiResult.success();
  }

  @ApiOperation(value = "删除课程", notes = "scheduleId参数不为空则删除指定ID的自定义课程，否则删除指定名称的教务课程")
  @ApiImplicitParams({
      @ApiImplicitParam(name = "scheduleId", value = "课程id", required = false, paramType = "query"),
      @ApiImplicitParam(name = "scheduleName", value = "课程名", required = true, paramType = "query"),
      @ApiImplicitParam(name = "userId", value = "用户id", required = true, paramType = "query")})
  @PostMapping("/own/delete")
  public ApiResult<?> deleteOwnSchedule(Integer scheduleId, @NotBlank String scheduleName,
      @NotNull Integer userId) {
    if (scheduleId != null) {
      scheduleService.deleteOwnScheduleByScheduleId(scheduleId);
    } else {
      scheduleService.addDeletedSchedule(scheduleName, userId);
    }
    return ApiResult.success();
  }

  @ApiOperation(value = "删除指定用户的所有自定义课程")
  @ApiImplicitParam(name = "userId", value = "用户id", required = true, paramType = "query")
  @PostMapping("/own/delete/all")
  public ApiResult<?> deleteAllOwnSchedule(@NotNull Integer userId) {
    scheduleService.deleteOwnScheduleByUserId(userId);
    return ApiResult.success();
  }

  @ApiOperation("获取指定用户删除的所有课程")
  @GetMapping("/own/showDeleted")
  public ApiResult<List<DeletedScheduleResult>> getDeletedSchedule(@NotNull Integer userId) {
    return ApiResult.success(scheduleService.getDeletedSchedule(userId));
  }


  @ApiImplicitParam(name = "deletedScheduleId", value = "被删除课程主键id", required = true, paramType = "path")
  @ApiOperation("恢复删除的教务课程")
  @PostMapping("/own/recover/{deletedScheduleId}")
  public ApiResult<?> recoverSchedule(@PathVariable Integer deletedScheduleId) {
    scheduleService.recoverDeletedSchedule(deletedScheduleId);
    return ApiResult.success();
  }


}
